<?php
/***********************************************************************
 * @package    IvanEngine
 * @subpackage Core
 * @author     Ivan <ivanzx@msn.com>
 * @created    2010-05-12
 ***********************************************************************/
if(defined("IVANENGINE_CORE_STL_STRING"))
	die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_CORE_STL_STRING", true);

require_once (dirname(__FILE__).'/../Base.php');

class CString extends CBase
{
	const  npos		= -1;
	protected
		$m_string	= "";

	public function __construct()
	{
		parent::__construct();
	}

	public function __destruct()
	{
		unset($this->m_string);
		parent::__destruct();
	}

	static public function From($string)
	{
		$str = new CString();
		$numargs 	= func_num_args();
		if ($numargs >= 2) {
			$arg_list 	= func_get_args();
			$temp_args	= array();
			for ($i = 1; $i < $numargs; $i++) {
				$temp_args[$i-1] = $arg_list[$i];
    		}
    		$str->Set(vsprintf($string, $temp_args));
		}else{
			$str->Set($string);
		}
		return $str;
	}
	
	public function Format($string)
	{
		$numargs 	= func_num_args();
		if ($numargs >= 2) {
			$arg_list 	= func_get_args();
			$temp_args	= array();
			for ($i = 1; $i < $numargs; $i++) {
				$temp_args[$i-1] = $arg_list[$i];
    		}
    		$this->m_string = vsprintf($string, $temp_args);
		}else{
			$this->m_string = $string;
		}
	}
	
	public function Set($string)
	{
		$this->m_string	= $string;
	}
	
	public function Get()
	{
		return $this->m_string;
	}
	
	public function Length()
	{
		return strlen($this->m_string);
	}
	
	public function IsEmpty()
	{
		return $this->Length() == 0;
	}
	
	public function Clear()
	{
		$m_string	= "";
	}
	
	public function GetAt($pos)
	{
		if( $pos > $this->Length() )
			return '\0';
		return $this->m_string[$pos];
	}
	
	public function SetAt($pos, $ch)
	{
		if( $pos > $this->Length() || strlen($ch) != 1 )
			return;
			
		$this->m_string[$pos]	= $ch;
	}
	
	public function Compare($string, $isCase = true)
	{
		if( $isCase )
			return strcmp($this->m_string, $string);
		else
        	return strcasecmp($this->m_string, $string);
	}
	
	public function Contains($string)
	{
		return $this->Find($string) != self::npos;
	}
	
	public function Find($string, $startPos = 0)
	{
		if ($startPos >= $this->Length() || $string == "" || $string[0] == '\0')
        {
            return self::npos;
        }
        
        $subStr = strpos($this->Substr($startPos, $this->Length()-$startPos), $string);

        if ($subStr === FALSE)
            return self::npos;
            
        return $subStr;	
	}
	
	public function FindReverse($string, $startPos = 0)
	{
		if ($startPos >= $this->Length() || $startPos == self::npos)
        {
            $startPos = $this->Length() - 1;
        }
        
        $length = strlen($string);

        if ($startPos + 1 < $length)
        {
            return self::npos;
        }

        $startPos = $startPos - $length + 2;

        while($startPos > 0)
        {
            $startPos--;
            if (!strncmp($this->SubStr($startPos,$this->Length()-$startPos),$string,$length))
                return $startPos;
        }

        return self::npos;
	}
	
	public function Cat($string)
	{
		$this->m_string .= $string;
	}
	
	public function SubStr($beginPos, $count = -1)
	{
        if( $count <= -1 )
		    return substr($this->m_string, $beginPos);
        else
            return substr($this->m_string, $beginPos, $count);
	}

	public function SubStrCmp($beginPos, $delimiters)
	{
		if ($beginPos < $this->Length() && $this->m_string != "" && $delimiters != "")
    	{
        	$str = strpbrk($this->SubStr($beginPos, self::npos), $delimiters);
        	if ($str == NULL)
        	{
            	if ($beginPos < $this->Length())
                	return $this->SubStr($beginPos, self::npos);
            	else
                	return "";
        	}
        	else
        	{
            	return $this->SubStr($beginPos, $this->Length()-strlen($str)-$beginPos-1);
        	}
    	}

    	return "";
	}
	
	public function Insert($pos, $string)
	{
		if( strlen( $string) == 0)
			return;
		$originalLength = $this->Length();
        $insertLength = strlen($string);
        
		if ($pos >= $originalLength)
        {
            $this->Cat($string);
            return;
        }
        
        $firstStr = $this->SubStr(0, $pos);
        $endStr	  = $this->SubStr($pos, $this->Length()-$pos);
        $this->m_string	= $firstStr.$string.$endStr;
	}
	
	public function Left($count)
	{
		return $this->SubStr(0, $count);
	}
	
	public function Right($count)
	{
		if ($count > $this->Length())
            $count = $this->Length();
		return $this->SubStr($this->Length()-$count, $count);
	}
	
	public function Replace($whatToReplace, $replaceWith, $isCase = true)
	{
		if( $isCase == true ){
			$this->m_string = str_replace($whatToReplace, $replaceWith, $this->m_string);
		}else{
			$this->m_string = str_ireplace($whatToReplace, $replaceWith, $this->m_string);
        }
	}
	
	public function RemoveRange($pos, $count)
	{
		$this->m_string = $this->SubStr(0, $pos).
			$this->SubStr($pos+$count, $this->Length()-($pos+$count));
	}
	
	public function TrimLeft($string = " ")
	{
        $ownLength = $this->Length();
        $length = strlen($string);
        $pos 	= 0;

        while($pos + $length <= $ownLength && 
        		!strncmp($this->SubStr($pos,$this->Length()-$pos),$string,$length))
        {
            $pos += $length;
        }

        if ($pos > 0)
        {
            $this->RemoveRange(0, $pos);
        }
        return $pos;
	}
	
	public function TrimRight($string = " ")
	{
		$ownLength = $this->Length();
        $length = strlen($string);
        $pos 	= 0;

        while($pos + $length <= $ownLength && !strncmp(
        		$this->SubStr($ownLength-$pos-$length,$this->Length()-($ownLength-$pos-$length)),
        		$string,$length))
        {
            $pos += $length;
        }

        if ($pos > 0)
        {
            $this->RemoveRange($ownLength-$pos-1, $pos);
        }
        return $pos;
	}
	
	public function Reverse()
	{
		if ($this->Length() < 2)
            return;

        $end 	= $this->Length() - 1;
        $tempStr= $this->GetString();

        for ($begin = 0; $begin < $end; $begin++, $end--)
        {
            $ch = $tempStr[$begin];
            $this->m_string[$begin] = $tempStr[$end];
            $this->m_string[$end] = $ch;
        }
	}
	
	public function ToLower()
	{
		$this->m_string = strtolower($this->m_string);
	}
	
	static public function StrToLower($string)
	{
		return strtolower($string);
	}
	
	public function ToUpper()
	{
		$this->m_string = strtoupper($this->m_string);
	}
	
    static public function StrToUpper($string)
    {
        return strtoupper($string);
    }
	
	public function FindFirstOf($string, $beginPos = 0)
	{
		if ($string == "" || $string[0] == '\0')
        {
            return self::npos;
        }

        $pos = strpos($this->SubStr($beginPos, $this->Length()-$beginPos), $string);

        if( $pos != false ){
			return $pos;
		}
		return self::npos;
	}
	
	public function FindLastOf($string, $beginPos = CString::npos)
	{
		$length = $this->Length();
        if ($length == 0 || $string == "" || $string[0] == '\0'){
            return self::npos;
        }

        if ($beginPos >= $length || $beginPos == self::npos){
            $beginPos = $length - 1;
        }

        while($beginPos > 0)
        {
            --$beginPos;
            if (strchr($string, $this->m_string[$beginPos]))
                return $beginPos;
        }

        return self::npos;
	}
	
	public function Split($delimiters, $count = 0)
	{
        return explode($delimiters, $this->m_string);
	}
}

?>